文件属性设置UI设计 – 初探Flex中自定义组件 Custom UI Component Example: Unix File Permission Setting

Categories: Flex; Tagged with: ; @ August 27th, 2008 22:04

[小站博客均为原创, 转载请保留以下信息:

作者:http://liguoliang.com 欢迎访问:Adobe上海用户组: http://riashanghai.com ]

一:目标

设计一个自定义组件,可以通过该UI初步读取或设置文件属性.

二:设计

概要设计:

* 1.界面使用checkbox.分别对应Ower,Group,Public的Read,Write,Excute权限
* 2.定义变量
* 3.定义get set函数,定义checkbox状态与permission的转换函数,相关Event;

详细设计:

命名:

组件名称:PermissionUI;

各checkbox命名:checkOwnerRead, checkOwnerWrite, checkOwerExecute, checkGroupRead, …, checkPublicExecute.

变量命名:private _permission;

函数命名: 初始化函数:private function init(); public function set permission(); public function get permission(); checkbox状态转换[permissioncheckbox状态改变响应函数]:private function checkHandler();permission转换为checkbox状态函数 public function permissionToCheck();

代码:

1.初始化:

/**
* 初始化Array与Dictionary,Array用于存放所有的checkbox,Dictionary为以checkbox为Key,以checkbox对应Permission为值的Dictionary;
* 用于在checkbox与permission之间的转换,即SET与GET函数中通过Permission转换为Checkbox状态与将checkbox状态转换为Permission;
*
* 注意Array中存放的并非为各个checkbox的id[即其变量名称],而是对象,也就是说Array中存放的是9个checkbox.同时Dict中的Key也是checkbox;
*/
private function inint():void{
_checkBoxArray = [checkOwerRead,checkOwerWrite,checkOwerExecute,checkGroupRead,checkGroupWrite,checkGroupExecute,
checkPublicRead,checkPublicWrite,checkPublicExecute];
_checkBoxAndPermissionDict = new Dictionary();
_checkBoxAndPermissionDict[checkOwerRead] = 400;
_checkBoxAndPermissionDict[checkOwerWrite] = 200;
_checkBoxAndPermissionDict[checkOwerExecute] = 100;
_checkBoxAndPermissionDict[checkGroupRead] = 40;
_checkBoxAndPermissionDict[checkGroupWrite] = 20;
_checkBoxAndPermissionDict[checkGroupExecute] = 10;
_checkBoxAndPermissionDict[checkPublicRead] = 4;
_checkBoxAndPermissionDict[checkPublicWrite] = 2;
_checkBoxAndPermissionDict[checkPublicExecute] = 1;
}

2.get函数

/**
* 定义Get函数,并设定为Bindable,以便在set之后立即改变permission的值
*/

[Bindable]
public  function get permission():int {
trace("get method is called");
return _permission;
}

3.set函数:

/**
* SET函数.通过传来的_permission值确定各个checkbox的选定状态;
* 调用函数permissionTocheck()来完成任务
*/

public function set permission(permission_:int):void {
_permission = permission_;
trace("set method called");
trace(_permission);
permissionToCheck();
}

4.checkbox状态转换[permissioncheckbox状态改变响应函数]:

/**
* 定义checkHandler函数,在checkbox状态改变时将其状态转换为permission值.
* 如果permission值改变,广播该事件,以便相关Bindable的值改变.
* 如果将_permission = _value变为permission = _value,则call一次set函数,导致checkbox的一次更新;
* 但后果就是因checkbox状态改变而导致permission改变,但因为调用了set函数,checkbox状态将更新一次.
* 即:因checkbox引起的改变又引起了checkbox的改变.
* 如果不使用propertyChangeEvent,则会引起死循环.
*
* 该函数通过循环checkBoxArray,遍历每一个checkbox,检查其是否被选中,如果被选中,则临时变量_value增加该checkbox在_checkBoxAndPermissionDict中对应的value.
* 达到通过判断checkbox选定状态,来确定_permission值的目的;
*/
public function checkHandler():int {
var _value:int = 0;
var i:int;
if (_checkBoxArray == null || _checkBoxAndPermissionDict == null){
inint();
}
for(i=0; i<_checkBoxArray.length; i++){
if (_checkBoxArray[i].selected == true){
_value += _checkBoxAndPermissionDict[_checkBoxArray[i]];
}
}

trace("Current Permission is " + _permission);
var _old:int = _permission;
_permission = _value;
// dispatch PropertyChanged Event,以便于Binding.定义的_old用于存放最初的permission值.
//_permission为最新的值.如有不同则dispatch,便于更新TestPermission的数据,完成get方法.
this.dispatchEvent(mx.events.PropertyChangeEvent.createUpdateEvent(this,"permission",_old,_permission));
return _permission;
}

5.permission转换为checkbox状态函数:

/**
* 通过遍历每个checkbox,判断临时变量temp[值为set函数的参数]与checkbox在Dict中对应值得大小来确定该checkbox是否选定,
* 因为Dict中的每个value都是从大到小排列的,如果temp大于某checkbox的对应value,则可以确定该checkbox需要选定.
* 同时,为了配合前端的手动修改,会通过直接修改permission而不是通过checkbox来修改permission,
* 必须应该每个checkbox在选定之前取消选定,否则前面选定的checkbox在permission手动修改之后仍旧保持选定状态.该语句置于for循环之内,
* 保证每次判断或是操作checkbox之前取消其选定状态.
*/
public function permissionToCheck():void {
var i:int;
var temp:int = _permission;
if (_checkBoxArray == null || _checkBoxAndPermissionDict == null){
inint();
}
for (i = 0; i<_checkBoxArray.length; i++){
_checkBoxArray[i].selected = false;
if (temp >=  _checkBoxAndPermissionDict[_checkBoxArray[i]]){
_checkBoxArray[i].selected = true;
temp -= _checkBoxAndPermissionDict[_checkBoxArray[i]];
}
}
trace("permission to check ");
}

三:测试

编写测试:

<![CDATA[
import com.Check;
[Bindable]
public var testPermissionUI:PermissionUI = new PermissionUI();
/**
* 初始化.
* 新建一个PermissionUI,放置于(20,20);
* 使用时可以将permission初始化为某获取文件权限的函数的返回值.
* 此处测试为707,同时将初始值在permissionTextInput中显示.
*/
public function onCreationComplete():void {
testPermissionUI.x = 20;
testPermissionUI.y = 20;
addChild(testPermissionUI);
testPermissionUI.permission = 707;

}
/**
* 用户手动修改permission的时候调用该函数,然后使用set permission,使用给出的permission确定各个checkbox的状态.
*/
public function setPermission():void{
testPermissionUI.permission = int(permissionTextInput.text);
}

四:抓图

五:出现问题及解决方法

1.MXML中自定义组件的使用.

由于对自定义组件理解不够深入,导致在测试时拖入permissionUI时无法使用,于是新建一个permissionUI,但仍旧无法运行.原因是拖入的自定义组件虽然显示并没有真正使用,而通过new permissionUI()创建的组件因为没有add,导致没有显示出来.应将自定义组件当作普通组件一样使用,拉入后应添加ID,以在函数中使用.也可通过AS代码中new来实例化,但必须通过addchild()使之显示于容器中.

2.对象与String,ID

在最开始的_checkBoxArray设计中,我使用了

_checkBoxArray = [“checkOwerRead”,”checkOwerWrite”,”checkOwerExecute”,”checkGroupRead”,”checkGroupWrite”,”checkGroupExecute”,
“checkPublicRead”,”checkPublicWrite”,”checkPublicExecute”];

在后续使用中使用了_checkBoxArray[i].selected

误以为只要名字与对应ID相同,便可对checkbox进行操作,但实际情况是作为string的checkOwerRead,是不具有 selected的属性的,只有作为checkbox才能使用该属性,将上述数组中的string元素换为checkbox元素即可.因为数组中是可以存放Object的,且Dictionary中key可以为任意类型.这是与HashMap不同的,HashMap的Key只能为String类型.

3.算法设计.

checkbox与int转换的最初思路:

1.checkbox–>int:分别判断checkbox是否被点击,如果checkOwnerRead被点击,则int自加400,如果是checkOwnerWrite被选中,则int再自增200,以此类推.

2.int–>checkbox:将int每一位分离出来,如果第一位为7,则Owner列全部选中,如果为6,则选中Read跟Write,如果为5,则选中Excute与Read,以此类推,实现非常复杂.

但如果使用Array与Dictionary组合,则会极大减少工作量.

1.checkbox–>int:通过遍历checkBoxArray中每个checkbox,检查其是否被选中,如果被选中,则int增加checkBoxAndPermissionDict中对应的value.

2.int–>checkbox:通过遍历每个checkbox,判断int与checkbox在中checkBoxAndPermissionDict对应值得大小来确定该checkbox是否选定.

4.测试时手动输入属性的实现

最开始时仅仅将input中的输入数值赋给permission,调用了set函数,但并不能有效完成任务.通过分析发现,因为之前初始化的 permission以将部分checkbox选中,新set的值在permissionToCheck()时,只会将应该选定但没有选定的 checkbox选中,但已经选定的checkbox不会变化,于是在permissionToCheck()的for循环中加入了:

_checkBoxArray[i].selected = false;

由于该语句置于for循环之内,保证每次判断或是操作checkbox之前取消其选定状态.

六:相关知识点总结

1.Bindable

2.自定义事件

3.Array Dictionary

<->



// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.